package org.xinhe.dubbo.usage.simple.gateway.routing;

import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.rpc.service.GenericService;
import com.netflix.client.ClientException;
import com.netflix.zuul.context.RequestContext;
import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.util.MultiValueMap;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.*;

/**
 * <p>Title: DubboRoutingFilter</p>
 * <p>Date: 2018/7/25 </p>
 * <p>Description: </p>
 *
 * @author sunxinhe
 */
public class DubboRoutingFilter extends SimpleHostRoutingFilter {
    protected ProxyRequestHelper helper;

    public DubboRoutingFilter(ProxyRequestHelper helper, ZuulProperties properties) {
        super(helper, properties);
        this.helper = helper;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        // TODO 从RequestContext构建请求信息
        RequestContext requestContext = RequestContext.getCurrentContext();

        //region 通过Dubbo的GenericService完成泛化调用
        // 引用远程服务
        // 该实例很重量，里面封装了所有与注册中心及服务提供方连接，请缓存
        ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
        // 弱类型接口名
        reference.setInterface("org.xinhe.dubbo.usage.simple.service.SimpleService");
//        reference.setVersion("1.0.0");
        // 声明为泛化接口
        reference.setGeneric(true);

        // 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
        GenericService genericService = reference.get();

        Object result = genericService.$invoke("loopback", null, null);

        //endregion
        try {
            setResponse(result);
        } catch (ClientException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }


    protected void setResponse(Object result) throws ClientException, IOException {

        this.helper.setResponse(200,
                new ByteArrayInputStream(result.toString().getBytes()), new HttpHeaders());
    }
}
